use serde::{Deserialize, Serialize};

// -------------------- set --------------------
pub(crate) static SETTING: DefaultSetting = DefaultSetting {
    user_start_money: 5000,
    fish_ripe_time: 2.0,
    fish_reward: 1000,
    start_pid: 0,
    start_pid_name: "三沙",
    end_pid: 1000,
    end_pid_name: "漠河",
    cat_start_money: 10000,
    max_step_time: 24.,
    play_time: 8.,
    start_sid: 0,
    end_sid: 118,
    money_cost_per_sid: 500,
    time_cost_per_sid: 1.,
    none_pid: 1000000,
    none_city_name: "none",
    none_sid: 1000000,
    none_sid_name: "none",
};

pub struct DefaultSetting {
    pub user_start_money: u32,
    pub fish_ripe_time: f32,
    pub fish_reward: u32,
    pub start_pid: u32,
    pub start_pid_name: &'static str,
    pub end_pid: u32,
    pub end_pid_name: &'static str,
    pub cat_start_money: u32,
    pub max_step_time: f32,
    pub play_time: f32,
    pub start_sid: u32,
    pub end_sid: u32,
    pub money_cost_per_sid: u32,
    pub time_cost_per_sid: f32,
    pub none_pid: u32,
    pub none_sid: u32,
    pub none_sid_name: &'static str,
    pub none_city_name: &'static str,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TravelLine {
    Left,
    Mid,
    Right,
    None,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Transport {
    Airplane,
    Train,
    Car,
    Bus,
    Ship,
    Motorbike,
    Sleigh,
    None,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TravelType {
    Play,
    Transport,
    End,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BaseInfo {
    pub travel_line: String,
    pub game_time: f32,
    pub client_second: f32,
    pub user_money: u32,
    pub is_fish_ripe: bool,
    pub last_reap_time: f32,
    pub cat_money: u32,
    pub cat_new_money: u32,
    pub is_end: bool,
    pub enum_line: TravelLine, // 无实际用途，避免wasm生成的代码有bug
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CurrentState {
    pub pid: u32,
    pub time: f32,
    pub need_time: f32,
    pub travel_type: TravelType,
    pub link_index: u32,
    pub transport: Transport,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CurrentProvincePlan {
    pub total_sids: Vec<u32>,
    pub plan_sids: Vec<u32>,
    pub cur_sid_index: usize,
    pub waster_sid_cnt: usize, // 被浪费掉的本可以用来游玩的景点数量
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HistoryInfo {
    pub passing_pids: Vec<u32>,
    pub cur_pid_played_sids: Vec<u32>,
    pub total_played_sids: Vec<u32>,
    pub pid_2_played_sids: Vec<Vec<u32>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ShowInfo {
    pub cur_el_name: String,
    pub cur_pid_name: String,
    pub cur_sid_name: String,
    pub cur_city_name: String,
    pub passing_pid_names: Vec<String>,
    pub cur_pid_played_sid_names: Vec<String>,
    pub total_played_sid_names: Vec<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Info {
    pub base: BaseInfo,
    pub state: CurrentState,
    pub plan: CurrentProvincePlan,
    pub hist: HistoryInfo,
    pub show: ShowInfo,
}

impl Info {
    pub fn new(line_str: String, client_second: f32) -> Info {
        Info {
            base: BaseInfo {
                travel_line: line_str,
                game_time: 0.,
                client_second,
                user_money: SETTING.user_start_money,
                is_fish_ripe: true,
                last_reap_time: 0.,
                cat_money: SETTING.cat_start_money,
                cat_new_money: 0,
                is_end: false,
                enum_line: TravelLine::None,
            },

            state: CurrentState {
                pid: SETTING.start_pid,
                travel_type: TravelType::Play,
                time: 0.,
                need_time: 1.,
                link_index: SETTING.none_pid,
                transport: Transport::None,
            },

            plan: CurrentProvincePlan {
                total_sids: Vec::new(),
                plan_sids: Vec::new(),
                cur_sid_index: 0,
                waster_sid_cnt: 0,
                // foods_to_eat: Vec::new(),
            },

            hist: HistoryInfo {
                passing_pids: vec![SETTING.start_pid],
                cur_pid_played_sids: Vec::new(),
                total_played_sids: Vec::new(),
                pid_2_played_sids: vec![vec![]],
            },

            show: ShowInfo {
                cur_el_name: "".to_string(),
                cur_pid_name: SETTING.start_pid_name.to_string(),
                cur_sid_name: SETTING.none_sid_name.to_string(),
                cur_city_name: SETTING.none_city_name.to_string(),
                passing_pid_names: vec![SETTING.start_pid_name.to_string()],
                cur_pid_played_sid_names: Vec::new(),
                total_played_sid_names: Vec::new(),
            },
        }
    }
}
